package cheme.ProcessModel;

import java.util.ArrayList;
import java.util.List;

import cheme.ProcessModel.Annotations.IAnnotation;
import cheme.ProcessModel.Interpreter.IRuleCheckVisitor;
import cheme.ProcessModel.Visitors.IModelVisitor;


public abstract class AbstractModelElement extends PropertyAwareObject implements IModelElement
{
	/*
	 * Serialization version identifier. (Set to default for now)
	 */
	
	private static final long serialVersionUID = 1L;
	
	/*
	 * Annotations are model elements added to figures to portray some feedback.
	 */
	
	transient private List<IAnnotation> annotations = null;
	
	/*
	 * Every model element has a parent (except for the root level element).
	 * This is important to the event mechanism and is enforced in the
	 * constructors of all model elements which require a parent specification.
	 * Interpretable elements will monitor children for changes. Parents, in
	 * turn, are monitored byt the ModelEnv and so the interpreter.
	 */
	
	protected IModelElement parent = null;
	
	public AbstractModelElement(IModelElement parent)
	{
		this.parent = parent;
	}
	
	public IModelElement getParent()
	{
		return parent;
	}

	public IModelElement getRoot()
	{
		IModelElement root = this;
		while(null != root.getParent())
		{
			root = root.getParent();
		}
		
		return root;
	}
	
	public List<IAnnotation> getAnnotations()
	{
		if(null == annotations)
		{
			annotations = new ArrayList<IAnnotation>();
		}
		
		return annotations;
	}
	
	public void addAnnotation(IAnnotation annotation)
	{
		getAnnotations().add(annotation);
		firePropertyChange(P_ANNOTATION, null, annotation);
	}
	
	public void removeAnnotation(IAnnotation annotation)
	{
		getAnnotations().remove(annotation);
		firePropertyChange(P_ANNOTATION, annotation, null);
	}
	
	public boolean isInitial()
	{
		return false;
	}
	
	public abstract Object accept(IModelVisitor visitor);
}
